﻿// Inner Fire 游戏引擎库
// 帧资源定义
//
// Copyright (c) 2025 by 尔西大帝. All rights reserved.
//
// 用于定义在帧资源中使用的结构。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2025-05-21

#pragma once

#include <DirectXMath.h>
#include <minwindef.h>
#include <graphics/graphics_def.h>
#include <graphics/instanced_def.h>

namespace ifire {


/// <summary>
/// 用于常规对象的缓冲区项目
/// </summary>
struct ObjectConstants {
  DirectX::XMFLOAT4X4 world = IDENTITY_4X4;
  DirectX::XMFLOAT4X4 tex_transform = IDENTITY_4X4;
  UINT material_index;
  DirectX::XMFLOAT2 DisplacementMapTexelSize = {1.0f, 1.0f};
  float GridSpatialStep = 1.0f;
};

constexpr auto OBJECT_CB_SIZE =
    calc_constant_buffer_size(sizeof(ObjectConstants));

/// <summary>
/// 用于材质的缓冲区项目
/// </summary>
struct MaterialConstants {
  DirectX::XMFLOAT4 diffuse_albedo = {1.0f, 1.0f, 1.0f, 1.0f};
  DirectX::XMFLOAT3 fresnel_r0 = {0.01f, 0.01f, 0.01f};
  float roughness = 0.25f;
  DirectX::XMFLOAT4X4 mat_transform = IDENTITY_4X4;
};

constexpr auto MATERIAL_CB_SIZE =
    calc_constant_buffer_size(sizeof(MaterialConstants));

/// <summary>
/// 用于Ssao（屏幕环境光遮蔽）的缓冲区项目
/// </summary>
struct SsaoConstants {
  DirectX::XMFLOAT4X4 Proj;
  DirectX::XMFLOAT4X4 InvProj;
  DirectX::XMFLOAT4X4 ProjTex;
  DirectX::XMFLOAT4 OffsetVectors[14];

  // For SsaoBlur.hlsl
  DirectX::XMFLOAT4 BlurWeights[3];

  DirectX::XMFLOAT2 InvRenderTargetSize = {0.0f, 0.0f};

  // Coordinates given in view space.
  float OcclusionRadius = 0.5f;
  float OcclusionFadeStart = 0.2f;
  float OcclusionFadeEnd = 2.0f;
  float SurfaceEpsilon = 0.05f;
};

constexpr auto SSAO_CB_SIZE = calc_constant_buffer_size(sizeof(SsaoConstants));


/// <summary>
/// 用于蒙皮骨骼
/// </summary>
constexpr int MAX_BONE_TRANSFORMS = 256;
struct SkinnedConstants {
  DirectX::XMFLOAT4X4 BoneTransforms[MAX_BONE_TRANSFORMS];
};

// 用于UI的常量缓冲区。UI的Vertex信息需要更改。但是Indies是永远固定的[0,1,2..]，所以只需要变Vertex就行。
constexpr int MAX_UI_UNIT = 2048;


/// <summary>
/// 用于纹理索引
/// </summary>
struct MaterialData {
  DirectX::XMFLOAT4 DiffuseAlbedo = {1.0f, 1.0f, 1.0f, 1.0f};

  // 这段填充4个。
  DirectX::XMFLOAT3 FresnelR0 = {0.01f, 0.01f, 0.01f};
  float Roughness = 64.0f;

  // Used in texture mapping.
  DirectX::XMFLOAT4X4 MatTransform = IDENTITY_4X4;

  UINT DiffuseMapIndex = 0;
  UINT NormalMapIndex = 0;
  UINT MaterialPad1;
  UINT MaterialPad2;
};

// 用于InstancedSprite的大小
constexpr auto INSTANCED_SPRITE_CB_SIZE =
    calc_constant_buffer_size(sizeof(InstancedSpriteConstants));

/// <summary>
/// FrameResource的创建定义。
/// </summary>
struct FrameResourceDesc {
  size_t PassCount;
  size_t ShadowPassCount;
  size_t ObjectCount;
  size_t SkinnedObjectCount;
  size_t MaterialCount;
  size_t UICount;
  size_t TextCount;
  size_t InstancedSprite;
  size_t MapBlock;
};


} // namespace ifire